﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace JunionRobotTaskManager.Repository
{
    public interface IBaseRepository<T> where T : class
    {


        #region  添加

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> AddAsync(T entity);

        bool Add(T entity);

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities">实体数据集合</param>
        /// <returns></returns>
       Task< bool> AddListAsync(IList<T> entities);

        /// <summary>
        /// 批量添加数据 异步方法
        /// </summary>
        /// <param name="entities">实体数据集合</param>
        /// <returns></returns>
        bool AddList(IList<T> entities);
        #endregion

        #region 修改
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> UpdateEntityAsync(T entity);


        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool UpdateEntity(T entity);

        /// <summary>
        /// 批量更新实体数据 同步方法
        /// </summary>
        /// <param name="entities">实体数据集合</param>
        /// <returns></returns>
        bool UpdateList(IList<T> entities);

        /// <summary>
        /// 批量更新实体数据 异步方法
        /// </summary>
        /// <param name="entities">实体数据集合</param>
        /// <returns></returns>
        Task<bool> UpdateListAsync(IList<T> entities);
        #endregion

        #region 删除

        #region 根据Id删除 

        /// <summary>
        /// 根据Id删除数据 异步方法
        /// </summary>
        /// <param name="id">主键或者唯一的字段</param>
        /// <returns></returns>
        Task<bool> DeleteByIdAsync(object id);

        /// <summary>
        /// 根据Id删除数据 同步方法
        /// </summary>
        /// <param name="id">主键或者唯一的字段</param>
        /// <returns></returns>
        bool DeleteById(object id);

        /// <summary>
        /// 根据ids批量删除 异步方法
        /// </summary>
        /// <param name="ids">主键数组或者唯一性字段数组</param>
        /// <returns></returns>
        Task<bool> DeleteByIdsAsync(object[] ids);

        /// <summary>
        /// 根据ids批量删除 同步方法
        /// </summary>
        /// <param name="ids">主键数组或者唯一性字段数组</param>
        /// <returns></returns>
        bool DeleteByIds(object[] ids);

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids">主键数组或者唯一性字段数组</param>
        /// <returns></returns>
        Task<bool> DeleteByIdsAsync(Expression<Func<T, bool>> func);

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="func">条件信息</param>
        /// <returns></returns>
         bool DeleteByCondition(Expression<Func<T, bool>> func);

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="func">条件信息</param>
        /// <returns></returns>
        Task< bool> DeleteByConditionAsync(Expression<Func<T, bool>> func);
        #endregion

        #region 删除根据实体类

        /// <summary>
        /// 根据实体删除
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        bool DeleteByEntity(T entity);

        /// <summary>
        /// 根据实体删除 异步方法
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<bool> DeleteByEntityAsync(T entity);


        #endregion

        #endregion

        #region 查找

        #region 根据键查询

        /// <summary>
        /// 功能描述:根据ID查询一条数据 异步方法
        /// </summary>
        /// <param name="id">Id主键</param>
        /// <returns></returns>
        Task<T> FindByIdAsync(object id);

        /// <summary>
        /// 功能描述:根据ID查询一条数据 同步方法
        /// </summary>
        /// <param name="id">Id主键</param>
        /// <returns></returns>
        T FindById(object id);


        #endregion

        #region 条件查询和全部查询

        /// <summary>
        /// 根据条件查询单个数据
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        Task<T> FindAsync(Expression<Func<T, bool>> func);

        /// <summary>
        /// 根据条件查询单个
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        T Find(Expression<Func<T, bool>> func);

        /// <summary>
        /// 查询全部的数据
        /// </summary>
        /// <returns></returns>
        Task<List<T>> QueryAsync();


        /// <summary>
        /// 查询全部的数据
        /// </summary>
        /// <returns></returns>
        List<T> Query();

        /// <summary>
        /// 自定义条件查询 异步方法
        /// </summary>
        /// <param name="func">Where条件</param>
        /// <returns></returns>
        Task<List<T>> QueryAsync(Expression<Func<T, bool>> func);

        /// <summary>
        /// 自定义条件查询 同步方法
        /// </summary>
        /// <param name="func">Where条件</param>
        /// <returns></returns>
        List<T> Query(Expression<Func<T, bool>> func);

        #endregion

        #region 存在性检查

        /// <summary>
        /// 检查是否存在 异步方法
        /// </summary>
        /// <param name="func">筛选条件表达式</param>
        /// <returns></returns>
        Task<bool> CheckExistAsync(Expression<Func<T, bool>> func);

        /// <summary>
        /// 检查是否存在 异步方法
        /// </summary>
        /// <param name="func">筛选条件表达式</param>
        /// <returns></returns>
        bool CheckExist(Expression<Func<T, bool>> func);

        #endregion

        #region 分页查询

        /// <summary>
        /// 分页查询 异步方法
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        Task<List<T>> QueryAsync(int page, int size, RefAsync<int> total);

        /// <summary>
        /// 分页查询 异步方法
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        List<T> Query(int page, int size, ref int total);


        /// <summary>
        /// 自定义条件分页查询
        /// </summary>
        /// <param name="func">筛选条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        /// <returns></returns>
        Task<List<T>> QueryAsync(Expression<Func<T, bool>> func, int page, int size, RefAsync<int> total);
       
        
        /// <summary>
        /// 自定义条件分页查询
        /// </summary>
        /// <param name="func">筛选条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        /// <returns></returns>
        List<T> Query(Expression<Func<T, bool>> func, int page, int size,ref int total);

        /// <summary>
        /// 多条件分页查询
        /// </summary>
        /// <param name="conditionalModels">多个条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        Task<List<T>> QueryAsync(List<IConditionalModel> conditionalModels, int page, int size, RefAsync<int> total);

        /// <summary>
        /// 多条件分页查询
        /// </summary>
        /// <param name="conditionalModels">多个条件</param>
        /// <param name="page">页码</param>
        /// <param name="size">分页大小</param>
        /// <param name="total">总数</param>
        /// <returns></returns>
        List<T> Query(List<IConditionalModel> conditionalModels, int page, int size, ref int total);
        #endregion

        #region 原始Sql查询

        /// <summary>
        /// 批量原始Sql查询 异步方法
        /// </summary>
        /// <param name="sql">sql查询语句</param>
        /// <returns></returns>
        Task<List<T>> SqlQueryToListAsync(string sql);

        /// <summary>
        /// 批量原始Sql查询 同步方法
        /// </summary>
        /// <param name="sql">sql查询语句</param>
        /// <returns></returns>
        List<T>  SqlQueryToList(string sql);

        /// <summary>
        /// 原始Sql查询,异步查询
        /// </summary>
        /// <param name="sql">sql查询</param>
        /// <returns></returns>
        Task<T> SqlQueryAsync(string sql);

        /// <summary>
        /// 原始Sql查询,同步查询
        /// </summary>
        /// <param name="sql">sql查询</param>
        /// <returns></returns>
        T SqlQuery(string sql);

        List<TEntity> SqlQueryToList<TEntity>(string sql);

        TEntity SqlQuery<TEntity>(string sql);

        /// <summary>
        /// 原始Sql 执行 增删改方法
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        Task<int> ExecuteCommandAsync(string sql);

        /// <summary>
        /// 原始Sql 执行 增删改方法
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        int ExecuteCommand(string sql);

        #endregion

        #endregion
    }
}
